﻿using CodeGenerator.Models;
using CodeGenerator.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodeGenerator.Template.Web.Models
{
    public partial class Model:ITemplate
    {
        public MetaData Data { get; set; }
        public List<LookupClassModel> lookups { get; set; }
        public List<PickupListModel> pickuplist { get; set; }

        public bool IsLookup(string modelName)
        {
            foreach (var lookup in lookups)
            {
                if (lookup.Name.Equals(modelName)) return true;
            }
            return false;
        }

        public string Filename
        {
            get { return "{ClassName}Model.cs"; }
        }
        public string FolderName
        {
            get { return ""; }
        }

        public bool IsGenerateOneTime { get { return false; } }
        public bool IsGenerateFolder { get { return false; } }
        public bool IsRequiredOnlyOneMember { get { return true; } }
        public GenerateStyle GenerateStyle { get { return GenerateStyle.Normal; } }

        public List<ListObjectMasterDetailFilter> ListMasterDetailFilter()
        {
            ClassModel classModel = Data.Models[0];

            List<AttributeModel> list = new List<AttributeModel>();
            List<ListObjectMasterDetailFilter> listMS = null;

            ClassServices.CodeGenBLClient CS = new ClassServices.CodeGenBLClient();

            list = classModel.GetAttributes().Where(a => a.DataType.Name.Equals("Master Detail")).ToList();

            if (list.Count > 0)
            {
                listMS = new List<ListObjectMasterDetailFilter>();

                foreach (var attribute in list)
                {
                    var DestClass = CS.GetClass(new ClassServices.ClassPkDto { ClassId = attribute.ChildClass.Id });
                    var filters = CS.GetMasterDetailFilter(new ClassServices.FilterPkDto { AttributeId = attribute.Id });

                    if (filters.Data != null)
                    {
                        for (int i = 0; i < filters.Data.Count; i++)
                        {
                            listMS.Add(new ListObjectMasterDetailFilter
                            {
                                Name = filters.Data[i].Name,
                                NameID = filters.Data[i].Name + "_ID" + filters.Data[i].Id,
                                Formula = SplitFormulaMasterDetailFilter(filters.Data[i].Formula, new ClassModel(DestClass.Data)),
                                AttributeMasterDetailName = attribute.Name,
                                ChildClassName = attribute.ChildClass.Name,
                                ID = filters.Data[i].Id,
                                FilterNameModel = "Filter" + filters.Data[i].Name
                            });
                        }
                    }
                }
            }

            return listMS;
        }

        public string SplitFormulaMasterDetailFilter(string formula, ClassModel DestClass)
        {

            string StrFormula = formula;
            string StrAttribute = string.Empty;
            string StrOperator = string.Empty;
            string StrValue = string.Empty;
            string[] splitWord = null;
            string[] splitformula = null;
            string splitAttr = null;
            int AttributeID = 0;
            string StrTotal = string.Empty;

            AttributeModel ListName = null;

            splitWord = StrFormula.Split(new string[] { "&&", "||" }, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < splitWord.Length; i++)
            {
                splitformula = splitWord[i].Split(new string[] { "==", ">=", "<=", "!=", "<", ">", "begin with", "end with", "contains with" }, 2, StringSplitOptions.RemoveEmptyEntries);
                splitAttr = splitWord[i].Trim();
                StrAttribute = splitformula[0].Trim();

                if (splitAttr.IndexOf("==") > -1)
                {
                    StrOperator = "==";
                }
                else if (splitAttr.IndexOf(">=") > -1)
                {
                    StrOperator = ">=";
                }
                else if (splitAttr.IndexOf("<=") > -1)
                {
                    StrOperator = "<=";
                }
                else if (splitAttr.IndexOf("!=") > -1)
                {
                    StrOperator = "!=";
                }
                else if (splitAttr.IndexOf("<") > -1)
                {
                    StrOperator = "<";
                }
                else if (splitAttr.IndexOf(">") > -1)
                {
                    StrOperator = ">";
                }
                else if (splitAttr.ToLower().IndexOf("begin with") > -1)
                {
                    StrOperator = "startswith";
                }
                else if (splitAttr.ToLower().IndexOf("end with") > -1)
                {
                    StrOperator = "endswith";
                }
                else if (splitAttr.ToLower().IndexOf("contains with") > -1)
                {
                    StrOperator = "contains";
                }

                AttributeID = Convert.ToInt32(StrAttribute);
                ListName = DestClass._attributes.Where(attr => attr.Id.Equals(AttributeID)).FirstOrDefault();

                if (DataTypeMapper.ForModels(ListName).ToLower() == "string")
                {

                    if (splitformula[1].Trim() == string.Empty)
                    {
                        StrValue = "\"\"";

                    }
                    else if (splitformula[1].Trim() == null)
                    {
                        StrValue = null;
                    }
                    else
                    {
                        StrValue = splitformula[1].Trim().Replace("\"", "\\\"");
                        StrValue = "\"" + StrValue + "\"";
                    }

                }
                else
                {
                    StrValue = splitformula[1].Trim();
                }


                if (DataTypeMapper.ForModels(ListName).ToLower() == "string")
                {
                    if ((StrOperator == "!=") || (StrOperator == "==") || (StrOperator == ">") || (StrOperator == "<") || (StrOperator == ">=") || (StrOperator == "<="))
                    {
                        StrTotal = ListName.Name + ".CompareTo(" + StrValue + ")" + StrOperator + "0";
                    }
                    else if (StrOperator.ToLower() == "contains")
                    {
                        StrTotal = ListName.Name + ".Contains(" + StrValue + ")";
                    }
                    else if (StrOperator.ToLower() == "startswith")
                    {
                        StrTotal = ListName.Name + ".StartsWith(" + StrValue + ")";
                    }
                    else if (StrOperator.ToLower() == "endswith")
                    {
                        StrTotal = ListName.Name + ".EndsWith(" + StrValue + ")";
                    }
                }
                else if ((DataTypeMapper.ForModels(ListName).ToLower() == "datetime") || (DataTypeMapper.ForModels(ListName).ToLower() == "datetime?"))
                {

                    StrTotal = ListName.Name + StrOperator + " DateTime.ParseExact(\"" + StrValue + "\", \"yyyy-MM-dd\", new System.Globalization.CultureInfo(\"en-US\"))";

                }
                else
                {

                    StrTotal = ListName.Name + StrOperator + StrValue;
                }
                StrFormula = StrFormula.Replace(splitAttr, " a." + StrTotal + " ");
            }

            StrFormula = "Where(a => " + StrFormula + " ).ToList();";

            return StrFormula;
        }

        public class ListObjectMasterDetailFilter
        {
            public string Name;
            public string NameID;
            public string Formula;
            public string AttributeMasterDetailName;
            public string ChildClassName;
            public string FilterNameModel;
            public int ID;
        }

        public bool HasEventMapper(ClassModel model)
        {
            var result = Data.EventMappers.FindAll(x => x.ClassModel.Id == model.Id);
            if (result.Count() > 0)
                return true;
            else
                return false;
        }
    }
}
